﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Security.Cryptography;

namespace ProxySearcher
{
    public partial class mainForm : Form
    {
        public struct ProxyStruct
        {
            public string type;
            public string ip;
            public string port;
            //public string status;
            public string remark;
        }
        List<ProxyStruct> PROXYLIST_AGENT = new List<ProxyStruct>();
        List<ProxyStruct> PROXYLIST_ALL = new List<ProxyStruct>();
        public bool DocumentCompleted = false;

        //private bool LastPageLOADED = false;
        List<string> UrlList = new List<string>();

        public mainForm()
        {
            InitializeComponent();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            ZHUCE.REGISTERED = ZHUCE.Judge_Whether_Registered();
            if (ZHUCE.REGISTERED)
            {
                ZHUCE.VisitCount = 10000000;
                RegeToolStripMenuItem.Text = "关于";
                RegeToolStripMenuItem.ForeColor = System.Drawing.Color.Black;
            }
            else
            {
                ZHUCE.VisitCount = 10;
                RegeToolStripMenuItem.Text = "关于";
            }
            UrlList.Add("http://www.cnproxy.com/proxy1.html");
            UrlList.Add("http://www.cnproxy.com/proxy2.html");
            UrlList.Add("http://www.cnproxy.com/proxy3.html");
            UrlList.Add("http://www.cnproxy.com/proxy4.html");
            UrlList.Add("http://www.cnproxy.com/proxy5.html");
            UrlList.Add("http://www.cnproxy.com/proxy6.html");
            UrlList.Add("http://www.cnproxy.com/proxy7.html");
            UrlList.Add("http://www.cnproxy.com/proxy8.html");
            UrlList.Add("http://www.cnproxy.com/proxy9.html");
            UrlList.Add("http://www.cnproxy.com/proxy10.html");

            UrlList.Add("http://www.cz88.net/proxy/index.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_2.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_3.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_4.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_5.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_6.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_7.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_8.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_9.aspx");
            UrlList.Add("http://www.cz88.net/proxy/http_10.aspx");


        }

        #region webbrowser
        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (webBrowser1.ReadyState != WebBrowserReadyState.Complete) 
            {
                logger_all("Loading " + this.webBrowser1.Url.AbsoluteUri);
            }
            else
            {
                logger_all("Loading " + this.webBrowser1.Url.AbsoluteUri + " Complete!");
                DocumentCompleted = true;
                StreamReader sr = new StreamReader(this.webBrowser1.DocumentStream, Encoding.GetEncoding("gb2312"));
                string proxyHtml = sr.ReadToEnd();
                if (this.webBrowser1.Url.AbsoluteUri.Contains("cz88"))
                {
                    catchProxyFromString_cz88(proxyHtml);
                }
                if (this.webBrowser1.Url.AbsoluteUri.Contains("cnproxy"))
                {
                    catchProxyFromString_cnproxy(proxyHtml);
                }
                
            }
        }
        private void webBrowser1_NewWindow(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }
        #endregion

        #region pickUp Proxy
        private void catchProxyFromString_cz88(string htmlSource)
        {
            PROXYLIST_AGENT.Clear();
            //  <tr><td>.+?</td></tr>
            //  <tr><td>((\d+\.){3}\d+)</td><td>(\d{2,5})</td><td>(.+?)</td><td>(\w+)</td><td><div\sclass="addr_style">(.+?)</div></td></tr>
            string patternSplit = "</td></tr>";
            string patternProxy = "<tr><td>((\\d+\\.){3}\\d+)</td><td>(\\d{2,5})</td><td>(.+?)</td><td>(\\w+)</td><td><div\\sclass=\"addr_style\">(.+?)</div>";
            string[] arrayProxy = Regex.Split(htmlSource, patternSplit, RegexOptions.IgnoreCase);
            Regex r = new Regex(patternProxy);
            foreach (string iPorxy in arrayProxy)
            {
                Match m = r.Match(iPorxy);
                ProxyStruct aProxy = new ProxyStruct();
                aProxy.type = "HTTP";
                aProxy.ip = m.Groups[1].ToString();
                aProxy.port = m.Groups[3].ToString();
                //aProxy.status = "";
                string pRemark = m.Groups[6].ToString();
                if (pRemark.Contains(" "))
                {
                    string[] pRemarkAgent = m.Groups[6].ToString().Split(new string[] { " " }, StringSplitOptions.None);
                    aProxy.remark = pRemarkAgent[0].Replace("CZ88.NET", "").Trim();
                }
                else
                {
                    aProxy.remark = m.Groups[6].ToString();
                }
                
                
                if (aProxy.ip != "" && aProxy.port != "")
                {
                    PROXYLIST_AGENT.Add(aProxy);
                }
            }
            logger_all("Catch: " + PROXYLIST_AGENT.Count.ToString());
            if (PROXYLIST_AGENT.Count > 0)
            {
                insertProxyToList();
            }
        }
        private void catchProxyFromString_cnproxy(string htmlSource)
        {
            PROXYLIST_AGENT.Clear();
            //  </tr>
            //  <tr><td>((\d+\.){3}\d+)<SCRIPT.+?"\:"((\+\w){2,5})\)</SCRIPT></td><td>([A-Z]+)</td><td>.+?</td><td>(.+?)</td>
            string patternSplit = "</tr>";
            string patternProxy = "<tr><td>((\\d+\\.){3}\\d+)<SCRIPT.+?\":\"((\\+\\w){2,5})\\)</SCRIPT></td><td>([A-Z]+)</td><td>.+?</td><td>(.+?)</td>";
            string[] arrayProxy = Regex.Split(htmlSource, patternSplit, RegexOptions.IgnoreCase);
            Regex r = new Regex(patternProxy);
            foreach (string iPorxy in arrayProxy)
            {
                Match m = r.Match(iPorxy);
                ProxyStruct aProxy = new ProxyStruct();
                aProxy.type = "HTTP";
                aProxy.ip = m.Groups[1].ToString();
                string pPort = m.Groups[3].ToString().Replace("+", "");
                pPort = pPort.Replace("d", "0");
                pPort = pPort.Replace("c", "1");
                pPort = pPort.Replace("k", "2");
                pPort = pPort.Replace("z", "3");
                pPort = pPort.Replace("m", "4");
                pPort = pPort.Replace("b", "5");
                pPort = pPort.Replace("w", "6");
                pPort = pPort.Replace("i", "7");
                pPort = pPort.Replace("r", "8");
                pPort = pPort.Replace("l", "9");
                aProxy.port = pPort; 
                
                string pRemark = m.Groups[6].ToString();
                if (pRemark.Contains("United States") || pRemark.Contains("South Africa"))
                {
                    aProxy.remark = m.Groups[6].ToString();
                }
                else if (pRemark.Contains(","))
                {
                    string[] pRemarkAgent = m.Groups[6].ToString().Split(new string[] { "," }, StringSplitOptions.None);
                    aProxy.remark = pRemarkAgent[pRemarkAgent.Length - 1].Trim();
                }
                else if(pRemark.Contains(" "))
                {
                    string[] pRemarkAgent = m.Groups[6].ToString().Split(new string[] { " " }, StringSplitOptions.None);
                    aProxy.remark = pRemarkAgent[0].Trim();
                }
                else
                {
                    aProxy.remark = m.Groups[6].ToString();
                }


                if (aProxy.ip != "" && aProxy.port != "")
                {
                    PROXYLIST_AGENT.Add(aProxy);
                }
            }
            logger_all("Catch: " + PROXYLIST_AGENT.Count.ToString());
            if (PROXYLIST_AGENT.Count > 0)
            {
                insertProxyToList();
            }
        }

        private bool checkDuplicatedIp(ProxyStruct proxy)
        {
            for (int i = 0; i < PROXYLIST_ALL.Count; i++)
            {
                if (PROXYLIST_ALL[i].ip == proxy.ip && PROXYLIST_ALL[i].port == proxy.port)
                {
                    return true;
                }
            }
            return false;
        }
        private void button_getProxy_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy != true)
            {
                backgroundWorker1.RunWorkerAsync();// 启动异步操作
            }
            button_getProxy.Enabled = false;
        }
        private void button_importProxy_Click(object sender, EventArgs e)
        {
            //127.0.0.1:80@HTTP#名称
            string fname = "proxyList.txt";
            FileInfo finfo = new FileInfo(fname);
            if (finfo.Exists)
            {
                finfo.Delete();
            }

            for (int i = 0; i < PROXYLIST_ALL.Count; i++)
            {
                if (!ZHUCE.REGISTERED && i > 10000)
                {
                    break;
                    //continue;
                }
                else
                {
                    string content = PROXYLIST_ALL[i].ip + ":" + PROXYLIST_ALL[i].port + "@" + PROXYLIST_ALL[i].type + "#" + PROXYLIST_ALL[i].remark;
                    using (FileStream fs = finfo.OpenWrite())
                    {
                        StreamWriter w = new StreamWriter(fs);
                        w.BaseStream.Seek(0, SeekOrigin.End);//设置写数据流的起始位置为文件流的末尾
                        if (i == 0)
                        {
                            DateTime currentTime = DateTime.Now;
                            content = currentTime.ToString("G") + "\r\n代理服务器列表如下：\r\n===================\r\n" + content;
                            //if (ZHUCE.REGISTERED)
                            //{
                            //    content = currentTime.ToString("G") + "代理服务器列表如下：\r\n===================\r\n" + content;
                            //}
                            //else
                            //{
                            //    content = currentTime.ToString("G") + "\r\n未注册版本，最多导出10条代理记录，代理服务器列表如下：\r\n===================\r\n" + content;
                            //}

                        }
                        w.Write(content + "\r\n");  //写入日志内容并换行  
                        w.Flush();
                        w.Close();  //关闭写数据流  
                    }
                }
            }

            System.Diagnostics.Process.Start("notepad.exe", fname);
            //button_importProxy.Enabled = false;
        }
        #endregion

        #region record
        private void logger_list(string content)
        {
            DateTime currentTime = DateTime.Now;
            string current_record = currentTime.ToString("T") + " " + content;
            listBox_log.Items.Add(current_record);
            listBox_log.TopIndex = this.listBox_log.Items.Count - (int)(this.listBox_log.Height / this.listBox_log.ItemHeight);
        }
        private void logger_file(string content)
        {
            string fname = "logfile.txt";
            FileInfo finfo = new FileInfo(fname);
            if (finfo.Exists && finfo.Length > 512000)
            {
                finfo.Delete();
            }
            using (FileStream fs = finfo.OpenWrite())
            {
                DateTime currentTime = DateTime.Now;
                string current_record = currentTime.ToString("T") + " " + content;
                StreamWriter w = new StreamWriter(fs);
                w.BaseStream.Seek(0, SeekOrigin.End);//设置写数据流的起始位置为文件流的末尾  
                w.Write(current_record + "\r\n");  //写入日志内容并换行  
                w.Flush();
                w.Close();  //关闭写数据流  
            }
        }
        private void logger_all(string log)
        {
            logger_list(log);
            logger_file(log);
        }
        #endregion

        #region regedit
        private void RegeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 aboutBox = new AboutBox1();
            aboutBox.ShowDialog();
        }
        #endregion

        #region datagridview
        private void insertProxyToList()
        {
            for (int i = 0; i < PROXYLIST_AGENT.Count; i++)
            {
                if (checkDuplicatedIp(PROXYLIST_AGENT[i]))
                {
                    //logger_list(PROXYLIST_AGENT[i].ip + ":" + PROXYLIST_AGENT[i].port + " duplicated!");
                    continue;
                }
                DataGridViewRow row_proxy = new DataGridViewRow();

                DataGridViewTextBoxCell cell_type = new DataGridViewTextBoxCell();
                cell_type.Value = PROXYLIST_AGENT[i].type;
                row_proxy.Cells.Add(cell_type);

                DataGridViewTextBoxCell cell_ip = new DataGridViewTextBoxCell();
                cell_ip.Value = PROXYLIST_AGENT[i].ip;
                row_proxy.Cells.Add(cell_ip);

                DataGridViewTextBoxCell cell_port = new DataGridViewTextBoxCell();
                cell_port.Value = PROXYLIST_AGENT[i].port;
                row_proxy.Cells.Add(cell_port);

                DataGridViewTextBoxCell cell_remark = new DataGridViewTextBoxCell();
                cell_remark.Value = PROXYLIST_AGENT[i].remark;
                row_proxy.Cells.Add(cell_remark);

                PROXYLIST_ALL.Add(PROXYLIST_AGENT[i]);
                dataGridView_ProxyServerList.Rows.Add(row_proxy);
            }
            logger_all("All: " + PROXYLIST_ALL.Count.ToString());
        }
        private void dataGridView_ProxyServerList_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            DataGridView dw = (DataGridView)sender;
            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dw.RowHeadersWidth - 4, e.RowBounds.Height);
            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
            dw.RowHeadersDefaultCellStyle.Font, rectangle,
            dw.RowHeadersDefaultCellStyle.ForeColor,
            TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }
        #endregion

        #region background
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < UrlList.Count; i++)
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    Random ro = new Random();
                    Thread.Sleep(ro.Next(3000, 6000));
                    this.webBrowser1.Navigate(UrlList[i]);
                    int cTime = 0;
                    DocumentCompleted = false;
                    while (true)
                    {
                        if (cTime > 5 || DocumentCompleted)
                        {
                            break;
                        }
                        Thread.Sleep(ro.Next(4000, 8000));    // 等待响应
                        cTime += 1;
                    }
                }
            }
        }

        #endregion


    }
}
